package com.keyue.security.service;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.keyue.common.constant.Constant;
import com.keyue.common.exception.BusinessException;
import com.keyue.domain.RoleEnum;
import com.keyue.domain.vo.UserVO;
import com.keyue.domain.vo.admin.AdminRoleSmallVO;
import com.keyue.domain.vo.admin.DeptSmallVO;
import com.keyue.domain.vo.admin.JobSmallVO;
import com.keyue.domain.vo.admin.RoleSmallVO;
import com.keyue.security.vo.JwtUser;
import com.keyue.service.admin.AdminRoleService;
import com.keyue.service.admin.AdminUserService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @date 2018-11-22
 */
@Service("userDetailsService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private AdminUserService userService;

    @Resource
    private AdminRoleService roleService;


    @Override
    public UserDetails loadUserByUsername(String username) {
        UserVO user = userService.findByUserName(username);
        if (Objects.isNull(user)) {
            throw new BusinessException("账号不存在");
        }
        if (!user.getEnabled()) {
            throw new BusinessException("账号未激活");
        }
        return createJwtUser(user);
    }

    /**
     * @param user
     * @return
     */
    private UserDetails createJwtUser(UserVO user) {
        return new JwtUser(
                user.getId(),
                user.getUserName(),
                user.getNickName(),
                user.getGender(),
                user.getPassword(),
                user.getAvatarName(),
                user.getEmail(),
                user.getPhone(),
                Optional.ofNullable(user.getDept()).map(DeptSmallVO::getName).orElse(null),
                Optional.ofNullable(user.getJob()).map(JobSmallVO::getName).orElse(null),
                roleService.mapToGrantedAuthorities(user),
                user.getEnabled(),
                user.getEnableFlag(),
                user.getCreateTime(),
                buildRoleSmall(user),
                user.getPwdResetTime()
        );
    }

    /**
     * @param user
     * @return
     */
    private AdminRoleSmallVO buildRoleSmall(UserVO user) {
        Set<RoleSmallVO> roleSmallVOS = user.getRoles();
        List<AdminRoleSmallVO> roleSmallVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(roleSmallVOS)) {
            roleSmallVOList = roleSmallVOS.stream().map(x -> {
                return AdminRoleSmallVO.builder().id(x.getId())
                        .code(RoleEnum.getCodeById(x.getId())).name(RoleEnum.getNameById(x.getId())).build();
            }).collect(Collectors.toList());
        }
        return CollectionUtils.isNotEmpty(roleSmallVOList) ? roleSmallVOList.get(Constant.ZERO) : null;
    }
}
